package com.junyuan.gsp.shiro;

import com.alibaba.fastjson.JSON;
import com.junyuan.gsp.bean.Result;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @Author: maxwellens
 */
public class JwtAndFormAuthenticationFilter extends FormAuthenticationFilter
{
    private static final String TOKEN = "token";

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response)
    {
        if (isJwtRequest(request))
        {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String token = httpServletRequest.getHeader(TOKEN);
            JwtToken jwtToken = new JwtToken(token);
            return jwtToken;
        } else
        {
            return super.createToken(request, response);
        }
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception
    {
        if (isJwtRequest(request))
        {
            AuthenticationToken token = createToken(request, response);
            Subject subject = getSubject(request, response);
            try
            {
                subject.login(token);
                return true;
            } catch (AuthenticationException e)
            {
                Result result = new Result(401, "authentication failed", e.getMessage());
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(JSON.toJSONString(result));
                response.flushBuffer();
                return false;
            }

        } else
        {
            return super.executeLogin(request, response);
        }
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception
    {
        return super.onAccessDenied(request, response);
    }

    @Override
    protected boolean isLoginRequest(ServletRequest request, ServletResponse response)
    {
        if (isJwtRequest(request))
        {
            return true;
        } else
        {
            return super.isLoginRequest(request, response);
        }
    }

    @Override
    protected boolean isLoginSubmission(ServletRequest request, ServletResponse response)
    {
        if (isJwtRequest(request))
        {
            return true;
        } else
        {
            return super.isLoginSubmission(request, response);
        }

    }

    /**
     * 是否是Jwt请求
     *
     * @param request
     * @return
     */
    private boolean isJwtRequest(ServletRequest request)
    {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader(TOKEN);
        if (StringUtils.isEmpty(token))
        {
            return false;
        } else
        {
            return true;
        }
    }
}
